#include "State_Game_Play.h"

GamePlay* GamePlay::init = 0;
extern D3DApp* gd3dApp; 

extern IDirectInputDevice8		*mJoystick[2]; // This will be changed to an area later...
extern DIJOYSTATE2				js;

GamePlay::GamePlay()
{
	//set up camera info
	mCameraRadius    = 10.0f;
	mCameraRotationY = 0.5 * D3DX_PI;
	mCameraHeight    = 5.0f;

	ballx = 0.0f;
	ballz = 0.0f;

	//set up players (balls)
	ball = new Ball(0.5f, 20, 20, 3.0f, 0.0f, 3.0f);	
	setupFX();
	
}

void GamePlay::Enter()
{
	
}

void GamePlay::Execute(D3DApp* g)
{
	//update();
	Draw();	
}

void GamePlay::Exit()
{
	//cout << "Exiting State_TwoPlayer\n";
}

void GamePlay::Draw()
{
	// The camera position/orientation relative to world space can 
	// change every frame based on input, so we need to rebuild the
	// view matrix every frame with the latest changes.
	buildViewMtx();	
	
	// Clear the backbuffer and depth buffer.
	HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0));

	HR(gd3dDevice->BeginScene());

	//setup rendering technique
	HR(mFX->SetTechnique(mhTech));

	//set effect parameters for initial use
	HR(mFX->SetMatrix(mhWVP, &(mView*mProj)));

	//begin pass
	UINT numPasses = 0;

	//begin fx rendering
	HR(mFX->Begin(&numPasses, 0));
	for(int i =0; i < numPasses; i++)
	{
		HR(mFX->BeginPass(i));
	//definition for translation maxtrix
	  D3DXMATRIX T;
	  D3DXMatrixTranslation(&T, ball->getPosX(), 0.0f, ball->getPosZ());
	  HR(mFX->SetMatrix(mhWVP, &(T*mView*mProj)));
	  HR(mFX->CommitChanges());
	 
	  //jon this section will probably change, but it shdn't affect u
	  ball->draw();

	  HR(mFX->EndPass());
	}

	HR(mFX->End());
	HR(gd3dDevice->EndScene());


	//mGfxStats->display();

	

	// Present the backbuffer.
	HR(gd3dDevice->Present(0, 0, 0, 0));
}
GamePlay* GamePlay::Instance()
{
	if(init == 0)
	{
		init = new GamePlay();
	}
	return init;
}

void GamePlay::setupFX()
{
	mFX = 0;

	ID3DXBuffer* mFXErrors = 0;

	//create the effects object, if there are errors, display them
		//the following functions takes in the device to attach it too (our Direct3DDevice),
		//the name of the file to pull the effects from
		//defines & includes -- this shd be 0 for us
		//any flags (I want to know if we have errors so I set the Debug flag)
		//the next parameter specifies if we are sharing variables in the fx file with other fx files, we
		//aren't so it is 0
		//the last two parameters are the addresses of pointers to the fx object and the error buffer
	HR(D3DXCreateEffectFromFile(gd3dDevice, "BallSmackers.fx", 0, 0, D3DXSHADER_DEBUG, 0, &mFX, &mFXErrors));

	if( mFXErrors )
		MessageBox(0, (char*)mFXErrors->GetBufferPointer(), 0, 0);

	//get handles
	mhTech = mFX->GetTechniqueByName("TransformTech");
	mhWVP = mFX->GetParameterByName(0, "gWVP");
}

//the following functions help set up the camera and the world view
void GamePlay::buildViewMtx()
{
	float x = mCameraRadius * cosf(mCameraRotationY);
	float z = mCameraRadius * sinf(mCameraRotationY);
	D3DXVECTOR3 pos(x, mCameraHeight, z);
	D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
	D3DXMatrixLookAtLH(&mView, &pos, &target, &up);
}

void GamePlay::buildProjMtx()
{
	float w = WIDTH;
	float h = HEIGHT;
	D3DXMatrixPerspectiveFovLH(&mProj, D3DX_PI * 0.25f, w/h, 1.0f, 5000.0f);
}
void GamePlay::cleanUp()
{
	ReleaseCOM(mFX);
}

void GamePlay::update(float dt)
{
	//i think we will neeed arrays of some of these variables if we do not move this to the ball class
	static float cursorDelay = 0.0f;
	static float timeAccum = 0.0f;
	static int prevJS = 0;
	mJoystick[0]->GetDeviceState(sizeof(DIJOYSTATE2), &js);
		
	if(((js.rgdwPOV[0] != -1) && js.rgdwPOV[0] == 0))// && (js.rgdwPOV[0] ^ prevJS))
	{
		ballz = -(dt * 5);
		ball->updatePosZ(ballz);
		
	}

	else if(((js.rgdwPOV[0] != -1) && js.rgdwPOV[0] == 9000))// && (js.rgdwPOV[0] ^ prevJS))
	{
		ballx = -(dt * 5);
		ball->updatePosX(ballx);
		//MessageBox(gd3dApp->getMainWindowHandle(), "2nd", "Error", 0);
	}

	else if(((js.rgdwPOV[0] != -1) && js.rgdwPOV[0] == 18000))// && (js.rgdwPOV[0] ^ prevJS))
	{
		ballz = dt * 5;
		ball->updatePosZ(ballz);
		//MessageBox(gd3dApp->getMainWindowHandle(), "3rd", "Error", 0);
	}

	else if(((js.rgdwPOV[0] != -1) && js.rgdwPOV[0] == 27000))// && (js.rgdwPOV[0] ^ prevJS))
	{
		ballx = dt * 5;
		ball->updatePosX(ballx);
		//MessageBox(gd3dApp->getMainWindowHandle(), "4th", "Error", 0);
	}

	else if((js.rgbButtons[0] & 0x80) && (prevJSButtons[0] ^ js.rgbButtons[0]))
	{
		
	}

	else if(js.rgbButtons[1] & 0x80 && (prevJSButtons[1] ^ js.rgbButtons[1]))
	{
		
	}

	else if(js.rgbButtons[2] & 0x80 && (prevJSButtons[2] ^ js.rgbButtons[2]))
	{
		
	}

	else if(js.rgbButtons[3] & 0x80 && (prevJSButtons[3] ^ js.rgbButtons[3]))
	{
		
	}
	else if(js.rgbButtons[9] & 0x80 && (prevJSButtons[9] ^ js.rgbButtons[9]))
	{
		
	}

	if(!(js.rgdwPOV[0] == 4500 || js.rgdwPOV[0] == 13500 || js.rgdwPOV[0] == 22500 || js.rgdwPOV[0] == 31500))
			prevJS = js.rgdwPOV[0];

	for(int i = 0; i < 12; i++)
	{
		prevJSButtons[i] = js.rgbButtons[i];
	}
}